.286
;------------------------------------------------------------------------------
@SetMode        MACRO   Vedio_mode
                mov     al,Vedio_mode
                xor     ah,ah
                int     10h
                ENDM
;------------------------------------------------------------------------------
@Read           MACRO   ofset,bytes,hand
                mov     bx,hand
                mov     cx,bytes
                lea     dx,ofset
                mov     ah,3Fh
                int     21h
                ENDM
;------------------------------------------------------------------------------
@MovFile        MACRO   handle,hi,lo,mode
                mov     bx,handle
                mov     cx,hi
                mov     dx,lo
                mov     ah,42h
                mov     al,mode
                int     21h
                ENDM
;------------------------------------------------------------------------------
up_key          equ     48h
down_key        equ     50h
left_key        equ     4bh
right_key       equ     4dh
esc_key         equ     01h
VGA             equ     13h
palette_L       equ     768
Need_memory     equ     4000h

CODE_SEG        SEGMENT
                ASSUME  CS:CODE_SEG
                ORG     100H

START:          JMP     BEGIN

header          label   byte

manufacturer    db      0
version         db      0
encoding        db      0
bits_per_Pixel  db      0
xmin            dw      0
ymin            dw      0
xmax            dw      0
ymax            dw      0
hres            dw      0
vres            dw      0
H_palette       db      48 dup (0)
reserved        db      0
colour_planes   db      0
bytes_per_line  dw      0aah
palette_type    dw      0
filler          db      58 dup (0)
header_L        =       $ - offset manufacturer

pcc_width       dw      0
pcc_depth       dw      0
delay           dw      0
delay_flag      db      0
set_pal_flag    db      0
handle          dw      0ffffh
mode            db      0
data_seg        dw      0
back_seg        dw      0
air_seg         dw      0
temp_seg        dw      0
;zoom_seg        dw      0
which_seg       dw      0
found_time      db      0
airback         db      'back.pcc',0
air             db      'bird.pcc',0
leave_flag           db      0
file_order      db      0
posy            dw      70
posx            dw      120
start_point     dw      0
counter         db      200
count1          dw      0
count2          dw      0

err_msg         db      'Memory not enough !',10,13,'$'

key_table       db      up_key,down_key,left_key,right_key
                db      esc_key
no_of_key       equ     $ - offset key_Table

key_address     dw      offset fup
                dw      offset fdown
                dw      offset fleft
                dw      offset fright
                dw      offset fesc

zoom_table      db      60,01
                db      30,01
                db      15,01
                db      08,01
                db      04,01
                db      02,01
                db      01,01
                db      01,02
                db      01,04
                db      01,08
                db      01,15
                db      01,30
                db      01,60
                db      0ffh

BEGIN:          mov     sp,offset sp_end
                mov     bx,offset data_buffer
                add     bx,15            ;add mcb
                mov     cl,4
                shr     bx,cl            ; / 16
                mov     ah,4ah           ;adjust memory
                int     21H
                mov     bx,2000h
                mov     ah,48h
                int     21h
                jnc     j13
j10:            mov     dx,offset err_msg
                jmp     quit

j13:            mov     data_seg,ax
                mov     bx,1000h
                mov     ah,48h
                int     21h
                jc      j10
                mov     back_seg,ax
                mov     bx,1000h
                mov     ah,48h
                int     21h
                jc      j10
                mov     air_seg,ax

                ;mov     bx,1000h
                ;mov     ah,48h
                ;int     21h
                ;jc      j10
                ;mov     zoom_seg,ax

                mov     bx,1000h
                mov     ah,48h
                int     21h
                jc      j10
                mov     temp_seg,ax

                call    SetVga

                mov     dx,offset airback

j30:            mov     ax,3d00h
                int     21h
                jnc     j40
j35:            @Setmode Mode
                jmp     quit2

j40:            mov     handle,ax
                mov     ax,back_seg
                mov     which_seg,ax
                mov     set_pal_flag,1
                call    read_pcc

                mov     dx,offset air
                mov     ax,3d00h
                int     21h
                jc      J35
                mov     handle,ax
                mov     ax,air_seg
                mov     which_seg,ax
                mov     set_pal_flag,0
                call    read_pcc
b10:            call    draw
b20:            mov     ax,0c00h
                int     21h
                xor     ah,ah
                int     16h
                push    cs
                push    cs
                pop     ds
                pop     es
                mov     di,offset key_table
                mov     cx,no_of_key
                mov     al,ah
                repnz   scasb
                jnz     b20
                mov     bx,cx
                sub     bx,no_of_key
                neg     bx
                dec     bx
                shl     bx,1
                mov     si,offset key_address
                call    [si+bx]
                jmp     short b10

b300:           @Setmode Mode
                jmp     short quit2

quit:           @Setmode Mode

                mov     ah,09h
                push    cs
                pop     ds
                int     21h

quit2:          mov     ah,4ch
                int     21h
;------------------------------------------------------------------------------
clear_key_buf:  pusha
                mov     ax,0c00h
                int     21h
                popa
                ret
;------------------------------------------------------------------------------
fup:            cmp     posy,5
                jz      fupx
                sub     posy,5
fupx:           ret
;------------------------------------------------------------------------------
fdown:          cmp     posy,200 - 25 - 5
                jz      fdownx
                add     posy,5
fdownx:         ret
;------------------------------------------------------------------------------
fleft:          cmp     posx,5
                jb      fleftx
                sub     posx,5
fleftx:         ret
;------------------------------------------------------------------------------
fright:         cmp     posx,320 - 38 - 5
                ja      frightx
                add     posx,5
frightx:        ret
;------------------------------------------------------------------------------
fesc:           pop     ax
                mov     ax,offset b300
                push    ax
                ret
;------------------------------------------------------------------------------
read_pcc:       @Read   header,header_L,handle
                jnc     j50
                jmp     j100

j50:            cmp     manufacturer,0ah
                jz      j52
j51:            jmp     j100
J52:            cmp     version,05
                jnz     j51
                @MovFile handle,0,0,2
                xor     bx,bx
                sub     ax,palette_L + 1     ;768 + 1 ,pass 0c sign
                sbb     dx,bx
                @MovFile handle,dx,ax,0
                @Read   palette,palette_L,handle   ; [lea dx,palette] in macro
                mov     si,dx
                jc      j100
                cmp     byte ptr [si],0ch
                jnz     j100
                @MovFile handle,0,128,0

                mov     ax,xmax
                sub     ax,xmin
                inc     ax
                mov     pcc_width,ax

j60:            mov     bx,ymax
                sub     bx,ymin
                inc     bx
                mov     pcc_depth,bx
                call    Unpackpcc

j100:           mov     bx,handle
                mov     ah,3eh
                int     21h
                ret
;------------------------------------------------------------------------------
draw:           call    draw_back
                call    draw_air
                call    buffer_to_scr
                ret
;------------------------------------------------------------------------------
draw_air:       mov     es,temp_seg
                mov     ds,air_seg
                cld
                mov     bp,25
                mov     ax,posy
                mov     bx,320
                mul     bx
                add     ax,posx
                mov     di,ax
                xor     si,si

draw10:         mov     cx,38
draw13:         lodsb
                cmp     al,0ffh
                jnz     draw15
                inc     di
                jmp     short draw17
draw15:         stosb
draw17:         loop    draw13

                dec     bp
                jz      draw20
                add     di,320-38
                add     si,320-38
                jmp     short draw10

draw20:         ret
;------------------------------------------------------------------------------
buffer_to_scr:  pusha
                push    ds
                push    es
                mov     ds,temp_seg
                mov     ax,0a000h
                mov     es,ax
                mov     cx,320 * 200 / 2
                cld
                xor     si,si
                xor     di,di
                rep     movsw
                pop     es
                pop     ds
                popa
                ret
;------------------------------------------------------------------------------
draw_back:      mov     ds,back_seg
                mov     es,temp_seg
                mov     cx,320 * 200 /2
                cld
                xor     si,si
                xor     di,di
                rep     movsw
                ret
;------------------------------------------------------------------------------
SetVga:         mov     ah,0fh
                int     10h
                mov     mode,al
                @SetMode vga
                ret
;------------------------------------------------------------------------------
SetvgaPal:      mov     cx,palette_L
                lea     si,palette[1]           ;pass 0c sign
                mov     di,si
set10:          lodsb
                shr     al,1                    ;11111100 to 00111111 6 bits
                shr     al,1
                stosb                           ;change pcc to color resiger
                loop    set10

                xor     bx,bx
                mov     cx,256
                lea     dx,palette[1]
                mov     ax,1012h                ;set all color resiger
                push    cs
                pop     es
                int     10h
                ret
;------------------------------------------------------------------------------
Unpackpcc:      cmp     set_pal_flag,0
                jz      UP2

                call    SetVgaPal

UP2:            xor     di,di           ;or any position
                cld
                mov     ax,which_seg
                mov     es,ax
                mov     bp,pcc_width

                mov     ax,data_seg
                mov     ds,ax

up5:            mov     ah,3fh
                mov     cx,0ffffh
                mov     bx,handle
                xor     dx,dx
                int     21h
                jnc     up7
                jmp     up40

up7:            cmp     ax,cx
                jnz     up8
                mov     ax,ds
                add     ax,1000h
                mov     ds,ax
                jmp     short up5

up8:            mov     ax,data_seg
                mov     ds,ax

up9:            mov     cx,0ffffh
                xor     si,si

up10:           lodsb
                mov     dl,al
                and     dl,11000000b
                cmp     dl,11000000b
                jz      up20
                cmp     al,0ffh
                jnz     up11
                inc     di
                jmp     short up12
up11:           stosb
up12:           dec     bp
                jnz     up15
                dec     pcc_depth
                jz      up30
                mov     bp,pcc_width
                add     di,320
                sub     di,bp
up15:           loop    up10

up16:           mov     ax,ds
                add     ax,1000h
                mov     ds,ax
                jmp     short up9

up20:           mov     bx,cx
                xor     ch,ch
                mov     cl,al
                and     cl,00111111b
                lodsb
up22:           ;cmp     al,0ffh
                ;jnz     up23
                ;inc     di
                ;jmp     up23_1
up23:           stosb
up23_1:         dec     bp
                jz      up24
                loop    up22
                jmp     up25

up24:           dec     pcc_depth
                jz      up30
                mov     bp,pcc_width
                add     di,320
                sub     di,bp

up25:           mov     cx,bx
                dec     cx
                jcxz    up16
                jmp     short up15

up30:           push    cs
                pop     ds
                cmp     delay_flag,0
                jz      up35
                mov     bp,delay
                shl     bp,1
up32:           xor     cx,cx
up33:           loop    up33
                dec     bp
                jnz     up32
                jmp     short up40

up35:
up40:           ret
;------------------------------------------------------------------------------
sp_end          equ     $  +  200

palette         equ     $  +  201        ;db      768 dup (0)

data_buffer      equ     $  + 1000

CODE_SEG        ENDS
                END  START

